package ge.modules.events;

import java.util.HashMap;

import ge.engine.Camera;
import ge.engine.Engine;
import ge.engine.Log;
import ge.engine.PositionableArea;
import ge.exceptions.FunctionNonSuported;
import ge.lowlevel.EventEngine;
import ge.modules.Module;

public class IOListener implements Module 
{
	private Double posX = null,posY = null;
	private boolean checkedKeyPressed = false;
	
	@Override
	public void update()
	{
		posX = posY = null;
		checkedKeyPressed = false;
		
	}

	@Override
	public void draw() {
	}
	
	/**
	 * 	Checks if the key is pressed
	 * 	It doesn't differences capital letter
	 * @param key Key to ask.
	 * @return True if its checked
	 */
	public boolean keyPressed(String key) 
	{
		 IOEventModule io = (IOEventModule) EventEngine.get().ask("keyPressed");
		 if(io != null)
		 {
			 boolean apretado = io.keyPressed(key);
			 checkedKeyPressed = (checkedKeyPressed?true:apretado);	
			 return apretado;
		 }
		 else
			 return false;
	}
	/**
	 * 	Checks if the key is pressed just in this moment
	 * 	It doesn't differences capital letter
	 * @param key Key to ask.
	 * @return True if its checked
	 */
	public boolean keyDown(String key) 
	{
		 IOEventModule io = (IOEventModule) EventEngine.get().ask("keyDown");
		 if(io != null)
		 {
			 boolean apretado = io.keyDown(key);
			 checkedKeyPressed = (checkedKeyPressed?true:apretado);	
			 return apretado;
		 }
		 else
			 return false;
	}
	/**
	 * 	Checks if a pressed key it's being dropped
	 * 	It doesn't differences capital letter
	 * @param key Key to ask.
	 * @return True if its checked
	 */
	public boolean keyUp(String key) 
	{
		 IOEventModule io = (IOEventModule) EventEngine.get().ask("keyUp");
		 if(io != null)
		 {
			 boolean apretado = io.keyUp(key);
			 checkedKeyPressed = (checkedKeyPressed?true:apretado);	
			 return apretado;
		 }
		 else
			 return false;
	}
	/**
	 * 	With that module you may check if one of some keys has been pressed, just pressed, or
	 *  up.
	 *  If one of this questions in that module it's true, something you asked happen,
	 *  then, wansAnyKeyChecked flag will be true.
	 *  
	 *  io.keyPress("A");
	 *  io.keyDown("B");
	 *  If one of each is true, it doesn't matter who, the flag will be true.
	 * @return True if one of the keyAnyFunction is true.
	 */
	public boolean wasAnyKeyChekced()
	{
		return checkedKeyPressed;
	}
	/**
	 *  Checks if the mouse button is pressed
	 * 	"LEFT" or "RIGHT" or "MIDDLE"
	 * @param button button to ask.
	 * @return True if its checked
	 */
	public boolean mouseDown(String button) 
	{
		 IOEventModule io = (IOEventModule) EventEngine.get().ask("mouseDown");
		 if(io != null)
		 {
			 return io.mouseDown(button);
		 }
		 else
			 return false;
	}
	/**
	 *  Checks if a pressed button it's being dropped
	 * 	"LEFT" or "RIGHT"
	 * @param button button to ask.
	 * @return True if its checked
	 */
	public boolean mouseUp(String button) 
	{ 
		 IOEventModule io = (IOEventModule) EventEngine.get().ask("mouseUp");
		 if(io != null)
		 {
			 return  io.mouseUp(button);
		 }
		 else
			 return false;
	}
	
	/**
	 *  Checks if we have make a double click with a button
	 * 	"LEFT" or "RIGHT" 
	 * @param button button to ask.
	 * @return True if its checked
	 */
	public boolean doubleClick(String button) 
	{
		 return mouseUp(button) && mouseDown(button);
	}
	
	/**
	 * 	The position x of the mouse
	 * @return The position x  local to the camera not to the world
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public Double mouseX()
	{
		if(posX == null)
			getMousePosition();
		return posX;
	}
	/**
	 * 	The position y of the mouse
	 * @return The position y local to the camera, not to the world
	 * @throws FunctionNonSuported if the engine doesn't support it
	 */
	public Double mouseY()
	{
		if(posY == null)
			getMousePosition();
		return posY;
	}
	/**
	 * 		Test if the mouse is over that area
	 * @param area PositionableArea object
	 * @return True if the mouse is inside the area
	 */
	public boolean mouseOverOn(PositionableArea area)
	{
		Double posX = mouseX();
		Double posY = mouseY();
		if(posX == null || posY == null)
			return false;
		
		//Log.write("("+posX+","+posY+")"+"("+area.getY()+","+area.getX()+")");
		if(area.getX() < posX && posX < area.getWidth()+area.getX())
		{
			if(area.getY() < posY && posY < area.getHeight()+area.getY())
				return true;
		}
		return false;
	}
	/**
	 * 	Check if you are pressing that button in that area. It's just a merge between mouseDown and mouseOverOn
	 *  in that order.
	 * @param area Area where to ask
	 * @param button  Mouse button to click
	 * @return True if you are clicking down in that area.
	 */
	public boolean mouseClickOn(PositionableArea area, String button)
	{ 
		 
		return mouseUp(button) && mouseOverOn(area);
	}
	private void getMousePosition()
	{
		IOEventModule io = (IOEventModule) EventEngine.get().ask("mouseX");
		if(io != null)
		{
			Camera c = Engine.getCamera();
			posX = c.getX() + io.mouseX();
			posY = c.getY() + io.mouseY();
		}	
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		
	}
	
	
}
